home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1997 September / Macworld (1997-09).dmg / Serious Software / Cherwell Scientific Demos / pro Fit / pro Fit 5.0 demo (fpu).sea / pro Fit 5.0 demo (fpu) / Functions & Programs / •Gadgets / Linear interpolation of data < prev    next >
Text File  |  1996-06-01  |  5KB  |  168 lines

  1. {
  2.     This function accesses the current data set of a window and returns
  3.  the linear interpolation between the data points. This function can be used
  4.  to compare two data sets that were measured using slightly different steps
  5.  for the x-coordinate. Based on the two data sets, it is possible to produce a
  6.  table with measured data at selected x-coordinates, and so on.
  7.  The function also offers the possibility of a multiplication factor and of x- 
  8.  and y-offsets.
  9.  
  10.  To use this function, choose "Add To Menu" from the Misc menu
  11.  (or click the Add button).
  12.  The function's name appears in the Func menu.
  13.  
  14.  Use it as you would use any other function. Click the "Choose Data" button
  15.  in the parameter window to  set the data set used by the function.
  16.  
  17.  If you are looking at the function in the preview window, you must click
  18.  "Redraw" whenever you change some data in its reference data set!
  19.  The function has no way to know that you are changing its data under its nose!
  20. }
  21.  
  22. function LinInterpol;
  23.  
  24. description 'returns the lin. interpolation of the current x- and y- data set in a given window.',
  25.             '$BChoose Data$Offsets Δx,Δy are available. Data MUST be ordered';
  26.  
  27. defaults   a[1]:=0,active,'Δx     (x-offset)';
  28.            a[2]:=0,active,'Δy     (y-offset)';
  29.            a[3]:=1,active,'ampl   (mulitplies all y-vals.)';
  30.  
  31. var dataWindow,xc,yc,globMin,globMax,yMin,yMax:extended;
  32.             iMax:integer; {last valid row number for data access}
  33.             j1,j2,Lastj:integer;
  34.  
  35. {the following two functions are used to access the data window.
  36.  They start looking in the data cell in row i. If in row i, both
  37.  xCol and yCol cells contain a valid number they return this number,
  38.  otherwise they increase i by one and look at the next data cell.
  39.  This is repeated until a valid cell is found or all cells have been
  40.  looked at. Both functions use the global variables xc and yc for
  41.  the data columns, and iMax for the last row used.
  42.  iMax is used (to spare time) instead of nrRows because it can
  43.  be that many empty rows follow the data set
  44. }
  45.  
  46. procedure Initialize;
  47. begin
  48.   dataWindow := 0;
  49.   xc := 0; yc := 0;
  50. end;
  51.  
  52. function xx(i:integer):extended;
  53. begin
  54.     if i<1 then xx:=-1/0 else
  55.     begin
  56.         while ((not dataok(i,xc)) or (not dataok(i,yc))) and (i<=iMax) do i:=i+1;
  57.         if i<=iMax then xx:=data[i,xc] else xx:=1/0;
  58.     end;
  59. end;
  60.  
  61. function yy(i:integer):extended;
  62. begin
  63.     if i<1 then yy:=-1/0 else
  64.     begin
  65.         while ((not dataok(i,xc)) or (not dataok(i,yc))) and (i<=iMax) do i:=i+1;
  66.         if i<=iMax then yy:=data[i,yc] else yy:=1/0;
  67.     end;
  68. end;
  69.  
  70. function check;
  71. begin
  72.     if pNumber=30000 then    {if the button was clicked}
  73.     begin
  74.         if dataWindow>0 then
  75.         begin
  76.             If GetWindowType(dataWindow)<>dataType then dataWindow:=0;
  77.         end;
  78.         Input('$WData Window',dataWindow,'$C$XX column',xc, '$C$YY column',yc);
  79.         if (dataWindow>0) then SetCurrentWindow(dataWindow);
  80.         SetDefaultCols(xc,yc,-1,-1);
  81.     end;
  82.     check:=ok;
  83. end;
  84.  
  85. procedure first;
  86. var counter:integer;
  87. begin
  88. if dataWindow>0 then
  89. begin
  90.     If GetWindowType(dataWindow)=dataType then 
  91.             SetCurrentWindow(dataWindow)
  92.     else 
  93.     begin    
  94.             dataWindow:=0;
  95.             SetCurrentWindow( FrontmostWindow(dataType) )
  96.     end;
  97. end;
  98.  
  99. if xc<=0 then xc:=xColumn;
  100. if yc<=0 then yc:=yColumn;
  101.  
  102.  counter:=NrRows+1;
  103.  repeat counter:=counter-1 until dataok(counter,xc) and dataok(counter,xc);
  104.  GlobMax:=data[counter,xc];ymax:=data[counter,yc];iMax:=counter;j2:=iMax;
  105.  GlobMin:=xx(1);ymin:=yy(1);j1:=1;Lastj:=j1;
  106.  end;
  107.  
  108. procedure find(lastIndex:integer;target:extended);
  109. {this procedure sets the global index-variables j1,j2 to point
  110.  to the x-values bracketing the target value. The procedure first looks
  111.  in the neighbourhood of the parameter lastindex. This means that
  112.  if first looks at j1=lastindex, j2=lastindex+1. If this is not
  113.  good, the procedure looks in the right direction (assuming that
  114.  the data are sorted), making always wider steps until target is
  115.  bracketed. Afterwards the copy j1,j2 is found with the bisection method.
  116. }
  117.  var    j:integer;
  118.                  p:integer;
  119.  begin
  120.     p:=1;
  121.     if xx(lastIndex)<=target then
  122.     begin
  123.         j2:=lastIndex+1;
  124.         while xx(j2)<target do
  125.         begin
  126.             p:=p+p;
  127.             j2:=j2+p;
  128.             if j2>iMax then j2:=iMax;
  129.         end;
  130.         j1:=j2-p;
  131.     end
  132.     else
  133.     begin
  134.         j1:=lastIndex-1;
  135.         while xx(j1)>target do
  136.         begin
  137.             p:=p+p;
  138.             j1:=j1-p;
  139.             if p<1 then p:=1;
  140.         end;
  141.         j2:=j1+p;
  142.     end;
  143.     
  144.     while (j2-j1)>1 do
  145.     begin
  146.              j:=round((j2+j1)/2-0.4999999);
  147.              if xx(j)>target then j2:=j else j1:=j;
  148.      end;
  149.      while (not dataok(j1,xc)) or (not dataok(j1,yc)) do j1:=j1+1;
  150.      while (not dataok(j2,xc)) or (not dataok(j2,yc)) do j2:=j2+1;
  151. end;
  152.  
  153. begin
  154.  x:=x+a[1];
  155.  
  156.  if x<GlobMin then
  157.          Find(Lastj,GlobMin)
  158.  else if x> Globmax then
  159.          Find(Lastj,Globmax)
  160.  else Find(Lastj,x);
  161.  
  162.  Lastj:=j1;
  163.  
  164.  y:=data[j1,yc]+(x-data[j1,xc])/(data[j2,xc]-data[j1,xc])*(data[j2,yc]-data[j1,yc]);
  165.  
  166.  y:=y*a[3];
  167.  y:=y+a[2];
  168. end;